home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / NEWSOFT / MAY / MP3CONV / !MP3Conv / c / ieeefloat < prev    next >
Text File  |  1997-02-17  |  28KB  |  966 lines

  1. /* Copyright (C) 1988-1991 Apple Computer, Inc.
  2.  * All Rights Reserved.
  3.  *
  4.  * Warranty Information
  5.  * Even though Apple has reviewed this software, Apple makes no warranty
  6.  * or representation, either express or implied, with respect to this
  7.  * software, its quality, accuracy, merchantability, or fitness for a 
  8.  * particular purpose.  As a result, this software is provided "as is,"
  9.  * and you, its user, are assuming the entire risk as to its quality
  10.  * and accuracy.
  11.  *
  12.  * This code may be used and freely distributed as long as it includes
  13.  * this copyright notice and the warranty information.
  14.  *
  15.  * Machine-independent I/O routines for IEEE floating-point numbers.
  16.  *
  17.  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  18.  * happens to be infinity on IEEE machines.  Unfortunately, it is
  19.  * impossible to preserve NaN's in a machine-independent way.
  20.  * Infinities are, however, preserved on IEEE machines.
  21.  *
  22.  * These routines have been tested on the following machines:
  23.  *    Apple Macintosh, MPW 3.1 C compiler
  24.  *    Apple Macintosh, THINK C compiler
  25.  *    Silicon Graphics IRIS, MIPS compiler
  26.  *    Cray X/MP and Y/MP
  27.  *    Digital Equipment VAX
  28.  *    Sequent Balance (Multiprocesor 386)
  29.  *    NeXT
  30.  *
  31.  *
  32.  * Implemented by Malcolm Slaney and Ken Turkowski.
  33.  *
  34.  * Malcolm Slaney contributions during 1988-1990 include big- and little-
  35.  * endian file I/O, conversion to and from Motorola's extended 80-bit
  36.  * floating-point format, and conversions to and from IEEE single-
  37.  * precision floating-point format.
  38.  *
  39.  * In 1991, Ken Turkowski implemented the conversions to and from
  40.  * IEEE double-precision format, added more precision to the extended
  41.  * conversions, and accommodated conversions involving +/- infinity,
  42.  * NaN's, and denormalized numbers.
  43.  *
  44.  * $Id: ieeefloat.c,v 1.1 1993/06/11 17:45:46 malcolm Exp $
  45.  *
  46.  * $Log: ieeefloat.c,v $
  47.  * Revision 1.1  1993/06/11  17:45:46  malcolm
  48.  * Initial revision
  49.  *
  50.  * 12/16/96 Johan Hagman    Commented out code not necessary
  51.  *                for mpeg3play 0.9 (with #if 0).
  52.  *
  53.  */
  54.  
  55. #include    <stdio.h>
  56. #include    <math.h>
  57. #include    "ieeefloat.h"
  58.  
  59. /****************************************************************
  60.  * The following two routines make up for deficiencies in many
  61.  * compilers to convert properly between unsigned integers and
  62.  * floating-point.  Some compilers which have this bug are the
  63.  * THINK_C compiler for the Macintosh and the C compiler for the
  64.  * Silicon Graphics MIPS-based Iris.
  65.  ****************************************************************/
  66.  
  67. #ifdef applec    /* The Apple C compiler works */
  68. # define FloatToUnsigned(f)    ((unsigned long)(f))
  69. # define UnsignedToFloat(u)    ((defdouble)(u))
  70. #else /* applec */
  71. # define FloatToUnsigned(f)    ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))
  72. # define UnsignedToFloat(u)    (((defdouble)((long)((u) - 2147483647L - 1))) + 2147483648.0)
  73. #endif /* applec */
  74.  
  75.  
  76. /****************************************************************
  77.  * Single precision IEEE floating-point conversion routines
  78.  ****************************************************************/
  79.  
  80. #define SEXP_MAX        255
  81. #define SEXP_OFFSET        127
  82. #define SEXP_SIZE        8
  83. #define SEXP_POSITION    (32-SEXP_SIZE-1)
  84.  
  85. #if 0
  86.  
  87. defdouble
  88. ConvertFromIeeeSingle(char* bytes)
  89. {
  90.     defdouble    f;
  91.     long    mantissa, expon;
  92.     long    bits;
  93.  
  94.     bits =    ((unsigned long)(bytes[0] & 0xFF) << 24)
  95.         |    ((unsigned long)(bytes[1] & 0xFF) << 16)
  96.         |    ((unsigned long)(bytes[2] & 0xFF) << 8)
  97.         |     (unsigned long)(bytes[3] & 0xFF);        /* Assemble bytes into a long */
  98.  
  99.     if ((bits & 0x7FFFFFFF) == 0) {
  100.         f = 0;
  101.     }
  102.  
  103.     else {
  104.         expon = (bits & 0x7F800000) >> SEXP_POSITION;
  105.         if (expon == SEXP_MAX) {        /* Infinity or NaN */
  106.             f = HUGE_VAL;        /* Map NaN's to infinity */
  107.         }
  108.         else {
  109.             if (expon == 0) {    /* Denormalized number */
  110.                 mantissa = (bits & 0x7fffff);
  111.                 f = ldexp((defdouble)mantissa, expon - SEXP_OFFSET - SEXP_POSITION + 1);
  112.             }
  113.             else {                /* Normalized number */
  114.                 mantissa = (bits & 0x7fffff) + 0x800000;    /* Insert hidden bit */
  115.                 f = ldexp((defdouble)mantissa, expon - SEXP_OFFSET - SEXP_POSITION);
  116.             }
  117.         }
  118.     }
  119.  
  120.     if (bits & 0x80000000)
  121.         return -f;
  122.     else
  123.         return f;
  124. }
  125.  
  126. #endif /* #if 0*/
  127.  
  128. /****************************************************************/
  129.  
  130.  
  131. void
  132. ConvertToIeeeSingle(defdouble num, char* bytes)
  133. {
  134.     long    sign;
  135.     long    bits;
  136.  
  137.     if (num < 0) {    /* Can't distinguish a negative zero */
  138.         sign = 0x80000000;
  139.         num *= -1;
  140.     } else {
  141.         sign = 0;
  142.     }
  143.  
  144.     if (num == 0) {
  145.         bits = 0;
  146.     }
  147.  
  148.     else {
  149.         defdouble fMant;
  150.         int expon;
  151.  
  152.         fMant = frexp(num, &expon);
  153.  
  154.         if ((expon > (SEXP_MAX-SEXP_OFFSET+1)) || !(fMant < 1)) {
  155.             /* NaN's and infinities fail second test */
  156.             bits = sign | 0x7F800000;        /* +/- infinity */
  157.         }
  158.  
  159.         else {
  160.             long mantissa;
  161.  
  162.             if (expon < -(SEXP_OFFSET-2)) {    /* Smaller than normalized */
  163.                 int shift = (SEXP_POSITION+1) + (SEXP_OFFSET-2) + expon;
  164.                 if (shift < 0) {    /* Way too small: flush to zero */
  165.                     bits = sign;
  166.                 }
  167.                 else {            /* Nonzero denormalized number */
  168.                     mantissa = (long)(fMant * (1L << shift));
  169.                     bits = sign | mantissa;
  170.                 }
  171.             }
  172.  
  173.             else {                /* Normalized number */
  174.                 mantissa = (long)floor(fMant * (1L << (SEXP_POSITION+1)));
  175.                 mantissa -= (1L << SEXP_POSITION);            /* Hide MSB */
  176.                 bits = sign | ((long)((expon + SEXP_OFFSET - 1)) << SEXP_POSITION) | mantissa;
  177.             }
  178.         }
  179.     }
  180.  
  181.     bytes[0] = bits >> 24;    /* Copy to byte string */
  182.     bytes[1] = bits >> 16;
  183.     bytes[2] = bits >> 8;
  184.     bytes[3] = bits;
  185. }
  186.  
  187.  
  188. /****************************************************************
  189.  * Double precision IEEE floating-point conversion routines
  190.  ****************************************************************/
  191.  
  192. #define DEXP_MAX        2047
  193. #define DEXP_OFFSET        1023
  194. #define DEXP_SIZE        11
  195. #define DEXP_POSITION    (32-DEXP_SIZE-1)
  196.  
  197. #if 0
  198.  
  199. defdouble
  200. ConvertFromIeeeDouble(char* bytes)
  201. {
  202.     defdouble    f;
  203.     long    mantissa, expon;
  204.     unsigned long first, second;
  205.  
  206.     first = ((unsigned long)(bytes[0] & 0xFF) << 24)
  207.         |    ((unsigned long)(bytes[1] & 0xFF) << 16)
  208.         |    ((unsigned long)(bytes[2] & 0xFF) << 8)
  209.         |     (unsigned long)(bytes[3] & 0xFF);
  210.     second= ((unsigned long)(bytes[4] & 0xFF) << 24)
  211.         |    ((unsigned long)(bytes[5] & 0xFF) << 16)
  212.         |    ((unsigned long)(bytes[6] & 0xFF) << 8)
  213.         |     (unsigned long)(bytes[7] & 0xFF);
  214.     
  215.     if (first == 0 && second == 0) {
  216.         f = 0;
  217.     }
  218.  
  219.     else {
  220.         expon = (first & 0x7FF00000) >> DEXP_POSITION;
  221.         if (expon == DEXP_MAX) {        /* Infinity or NaN */
  222.             f = HUGE_VAL;        /* Map NaN's to infinity */
  223.         }
  224.         else {
  225.             if (expon == 0) {    /* Denormalized number */
  226.                 mantissa = (first & 0x000FFFFF);
  227.                 f = ldexp((defdouble)mantissa, expon - DEXP_OFFSET - DEXP_POSITION + 1);
  228.                 f += ldexp(UnsignedToFloat(second), expon - DEXP_OFFSET - DEXP_POSITION + 1 - 32);
  229.             }
  230.             else {                /* Normalized number */
  231.                 mantissa = (first & 0x000FFFFF) + 0x00100000;    /* Insert hidden bit */
  232.                 f = ldexp((defdouble)mantissa, expon - DEXP_OFFSET - DEXP_POSITION);
  233.                 f += ldexp(UnsignedToFloat(second), expon - DEXP_OFFSET - DEXP_POSITION - 32);
  234.             }
  235.         }
  236.     }
  237.  
  238.     if (first & 0x80000000)
  239.         return -f;
  240.     else
  241.         return f;
  242. }
  243.  
  244. #endif /* #if 0*/
  245.  
  246. /****************************************************************/
  247.  
  248. void
  249. ConvertToIeeeDouble(defdouble num, char *bytes)
  250. {
  251.     long    sign;
  252.     long    first, second;
  253.  
  254.     if (num < 0) {    /* Can't distinguish a negative zero */
  255.         sign = 0x80000000;
  256.         num *= -1;
  257.     } else {
  258.         sign = 0;
  259.     }
  260.  
  261.     if (num == 0) {
  262.         first = 0;
  263.         second = 0;
  264.     }
  265.  
  266.     else {
  267.         defdouble fMant, fsMant;
  268.         int expon;
  269.  
  270.         fMant = frexp(num, &expon);
  271.  
  272.         if ((expon > (DEXP_MAX-DEXP_OFFSET+1)) || !(fMant < 1)) {
  273.             /* NaN's and infinities fail second test */
  274.             first = sign | 0x7FF00000;        /* +/- infinity */
  275.             second = 0;
  276.         }
  277.  
  278.         else {
  279.             long mantissa;
  280.  
  281.             if (expon < -(DEXP_OFFSET-2)) {    /* Smaller than normalized */
  282.                 int shift = (DEXP_POSITION+1) + (DEXP_OFFSET-2) + expon;
  283.                 if (shift < 0) {    /* Too small for something in the MS word */
  284.                     first = sign;
  285.                     shift += 32;
  286.                     if (shift < 0) {    /* Way too small: flush to zero */
  287.                         second = 0;
  288.                     }
  289.                     else {            /* Pretty small demorn */
  290.                         second = FloatToUnsigned(floor(ldexp(fMant, shift)));
  291.                     }
  292.                 }
  293.                 else {            /* Nonzero denormalized number */
  294.                     fsMant = ldexp(fMant, shift);
  295.                     mantissa = (long)floor(fsMant);
  296.                     first = sign | mantissa;
  297.                     second = FloatToUnsigned(floor(ldexp(fsMant - mantissa, 32)));
  298.                 }
  299.             }
  300.  
  301.             else {                /* Normalized number */
  302.                 fsMant = ldexp(fMant, DEXP_POSITION+1);
  303.                 mantissa = (long)floor(fsMant);
  304.                 mantissa -= (1L << DEXP_POSITION);            /* Hide MSB */
  305.                 fsMant -= (1L << DEXP_POSITION);
  306.                 first = sign | ((long)((expon + DEXP_OFFSET - 1)) << DEXP_POSITION) | mantissa;
  307.                 second = FloatToUnsigned(floor(ldexp(fsMant - mantissa, 32)));
  308.             }
  309.         }
  310.     }
  311.     
  312.     bytes[0] = first >> 24;
  313.     bytes[1] = first >> 16;
  314.     bytes[2] = first >> 8;
  315.     bytes[3] = first;
  316.     bytes[4] = second >> 24;
  317.     bytes[5] = second >> 16;
  318.     bytes[6] = second >> 8;
  319.     bytes[7] = second;
  320. }
  321.  
  322.  
  323. /****************************************************************
  324.  * Extended precision IEEE floating-point conversion routines
  325.  ****************************************************************/
  326.  
  327. defdouble
  328. ConvertFromIeeeExtended(char* bytes)
  329. {
  330.     defdouble    f;
  331.     long    expon;
  332.     unsigned long hiMant, loMant;
  333.  
  334. #ifdef    TEST    
  335. fprintf(stderr, "ConvertFromIEEEExtended(%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx,%lx\r",
  336.     (long)bytes[0], (long)bytes[1], (long)bytes[2], (long)bytes[3], 
  337.     (long)bytes[4], (long)bytes[5], (long)bytes[6], 
  338.     (long)bytes[7], (long)bytes[8], (long)bytes[9]);
  339. #endif
  340.     
  341.     expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
  342.     hiMant    =    ((unsigned long)(bytes[2] & 0xFF) << 24)
  343.             |    ((unsigned long)(bytes[3] & 0xFF) << 16)
  344.             |    ((unsigned long)(bytes[4] & 0xFF) << 8)
  345.             |    ((unsigned long)(bytes[5] & 0xFF));
  346.     loMant    =    ((unsigned long)(bytes[6] & 0xFF) << 24)
  347.             |    ((unsigned long)(bytes[7] & 0xFF) << 16)
  348.             |    ((unsigned long)(bytes[8] & 0xFF) << 8)
  349.             |    ((unsigned long)(bytes[9] & 0xFF));
  350.  
  351.     if (expon == 0 && hiMant == 0 && loMant == 0) {
  352.         f = 0;
  353.     }
  354.     else {
  355.         if (expon == 0x7FFF) {    /* Infinity or NaN */
  356.             f = HUGE_VAL;
  357.         }
  358.         else {
  359.             expon -= 16383;
  360.             f  = ldexp(UnsignedToFloat(hiMant), expon-=31);
  361.             f += ldexp(UnsignedToFloat(loMant), expon-=32);
  362.         }
  363.     }
  364.  
  365.     if (bytes[0] & 0x80)
  366.         return -f;
  367.     else
  368.         return f;
  369. }
  370.  
  371.  
  372. /****************************************************************/
  373.  
  374. void
  375. ConvertToIeeeExtended(defdouble num, char *bytes)
  376. {
  377.     int    sign;
  378.     int expon;
  379.     defdouble fMant, fsMant;
  380.     unsigned long hiMant, loMant;
  381.  
  382.     if (num < 0) {
  383.         sign = 0x8000;
  384.         num *= -1;
  385.     } else {
  386.         sign = 0;
  387.     }
  388.  
  389.     if (num == 0) {
  390.         expon = 0; hiMant = 0; loMant = 0;
  391.     }
  392.     else {
  393.         fMant = frexp(num, &expon);
  394.         if ((expon > 16384) || !(fMant < 1)) {    /* Infinity or NaN */
  395.             expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
  396.         }
  397.         else {    /* Finite */
  398.             expon += 16382;
  399.             if (expon < 0) {    /* denormalized */
  400.                 fMant = ldexp(fMant, expon);
  401.                 expon = 0;
  402.             }
  403.             expon |= sign;
  404.             fMant = ldexp(fMant, 32);          fsMant = floor(fMant); hiMant = FloatToUnsigned(fsMant);
  405.             fMant = ldexp(fMant - fsMant, 32); fsMant = floor(fMant); loMant = FloatToUnsigned(fsMant);
  406.         }
  407.     }
  408.     
  409.     bytes[0] = expon >> 8;
  410.     bytes[1] = expon;
  411.     bytes[2] = hiMant >> 24;
  412.     bytes[3] = hiMant >> 16;
  413.     bytes[4] = hiMant >> 8;
  414.     bytes[5] = hiMant;
  415.     bytes[6] = loMant >> 24;
  416.     bytes[7] = loMant >> 16;
  417.     bytes[8] = loMant >> 8;
  418.     bytes[9] = loMant;
  419. }
  420.  
  421. #if 0
  422.  
  423. /****************************************************************
  424.  * Testing routines for the floating-point conversions.
  425.  ****************************************************************/
  426.  
  427. #ifdef METROWERKS
  428. #define IEEE
  429. #endif
  430. #ifdef applec
  431. # define IEEE
  432. #endif /* applec */
  433. #ifdef THINK_C
  434. # define IEEE
  435. #endif /* THINK_C */
  436. #ifdef sgi
  437. # define IEEE
  438. #endif /* sgi */
  439. #ifdef sequent
  440. # define IEEE
  441. # define LITTLE_ENDIAN
  442. #endif /* sequent */
  443. #ifdef sun
  444. # define IEEE
  445. #endif /* sun */
  446. #ifdef NeXT
  447. # define IEEE
  448. #endif /* NeXT */
  449.  
  450. #ifdef MAIN
  451.  
  452. union SParts {
  453.     Single s;
  454.     long i;
  455. };
  456. union DParts {
  457.     Double d;
  458.     long i[2];
  459. };
  460. union EParts {
  461.     defdouble e;
  462.     short i[6];
  463. };
  464.  
  465.  
  466. int
  467. GetHexValue(int x)
  468. {
  469.     x &= 0x7F;
  470.     
  471.     if ('0' <= x && x <= '9')
  472.         x -= '0';
  473.     else if ('a' <= x && x <= 'f')
  474.         x = x - 'a' + 0xA;
  475.     else if ('A' <= x && x <= 'F')
  476.         x = x - 'A' + 0xA;
  477.     else
  478.         x = 0;
  479.     
  480.     return(x);
  481. }
  482.  
  483.  
  484. void
  485. Hex2Bytes(char *hex, char *bytes)
  486. {
  487.     for ( ; *hex; hex += 2) {
  488.         *bytes++ = (GetHexValue(hex[0]) << 4) | GetHexValue(hex[1]);
  489.         if (hex[1] == 0)
  490.             break;    /* Guard against odd bytes */
  491.     }
  492. }
  493.  
  494.  
  495. int
  496. GetHexSymbol(int x)
  497. {
  498.     x &= 0xF;
  499.     if (x <= 9)
  500.         x += '0';
  501.     else
  502.         x += 'A' - 0xA;
  503.     return(x);
  504. }
  505.  
  506.  
  507. void
  508. Bytes2Hex(char *bytes, char *hex, int nBytes)
  509. {
  510.     for ( ; nBytes--; bytes++) {
  511.         *hex++ = GetHexSymbol(*bytes >> 4);
  512.         *hex++ = GetHexSymbol(*bytes);
  513.     }
  514.     *hex = 0;
  515. }
  516.  
  517.  
  518. void
  519. MaybeSwapBytes(bytes, nBytes)
  520. char* bytes;
  521. int nBytes;
  522. {
  523. #ifdef LITTLE_ENDIAN
  524.     char *p, *q, t;
  525.     for (p = bytes, q = bytes+nBytes-1; p < q; p++, q--) {
  526.         t = *p;
  527.         *p = *q;
  528.         *q = t;
  529.     }
  530. #else
  531.     if (bytes, nBytes);        /* Just so it's used */
  532. #endif /* LITTLE_ENDIAN */
  533.     
  534. }
  535.  
  536.  
  537. float
  538. MachineIEEESingle(bytes)
  539. char* bytes;
  540. {
  541.     float t;
  542.     MaybeSwapBytes(bytes, 4);
  543.     t = *((float*)(bytes));
  544.     MaybeSwapBytes(bytes, 4);
  545.     return (t);
  546. }
  547.  
  548.  
  549. Double
  550. MachineIEEEDouble(bytes)
  551. char* bytes;
  552. {
  553.     Double t;
  554.     MaybeSwapBytes(bytes, 8);
  555.     t = *((Double*)(bytes));
  556.     MaybeSwapBytes(bytes, 8);
  557.     return (t);
  558. }
  559.  
  560.  
  561. void
  562. TestFromIeeeSingle(hex)
  563. char *hex;
  564. {
  565.     defdouble f;
  566.     union SParts p;
  567.     char bytes[4];
  568.  
  569.     Hex2Bytes(hex, bytes);
  570.     f = ConvertFromIeeeSingle(bytes);
  571.     p.s = f;
  572.  
  573. #ifdef IEEE
  574.     fprintf(stderr, "IEEE(%g) [%s] --> float(%g) [%08lX]\n",
  575.     MachineIEEESingle(bytes),
  576.     hex, f, p.i);
  577. #else /* IEEE */
  578.     fprintf(stderr, "IEEE[%s] --> float(%g) [%08lX]\n", hex, f, p.i);
  579. #endif /* IEEE */
  580. }
  581.  
  582.  
  583. void
  584. TestToIeeeSingle(f)
  585. defdouble f;
  586. {
  587.     union SParts p;
  588.     char bytes[4];
  589.     char hex[8+1];
  590.  
  591.     p.s = f;
  592.  
  593.     ConvertToIeeeSingle(f, bytes);
  594.     Bytes2Hex(bytes, hex, 4);
  595. #ifdef IEEE
  596.     fprintf(stderr, "float(%g) [%08lX] --> IEEE(%g) [%s]\n",
  597.         f, p.i,
  598.         MachineIEEESingle(bytes),
  599.         hex
  600.     );
  601. #else /* IEEE */
  602.     fprintf(stderr, "float(%g) [%08lX] --> IEEE[%s]\n", f, p.i, hex);
  603. #endif /* IEEE */
  604. }
  605.  
  606.  
  607. void
  608. TestFromIeeeDouble(hex)
  609. char *hex;
  610. {
  611.     defdouble f;
  612.     union DParts p;
  613.     char bytes[8];
  614.     
  615.     Hex2Bytes(hex, bytes);
  616.     f = ConvertFromIeeeDouble(bytes);
  617.     p.d = f;
  618.  
  619. #ifdef IEEE
  620.     fprintf(stderr, "IEEE(%g) [%.8s %.8s] --> double(%g) [%08lX %08lX]\n",
  621.     MachineIEEEDouble(bytes),
  622.     hex, hex+8, f, p.i[0], p.i[1]);
  623. #else /* IEEE */
  624.     fprintf(stderr, "IEEE[%.8s %.8s] --> double(%g) [%08lX %08lX]\n",
  625.         hex, hex+8, f, p.i[0], p.i[1]);
  626. #endif /* IEEE */
  627.  
  628. }
  629.  
  630. void
  631. TestToIeeeDouble(f)
  632. defdouble f;
  633. {
  634.     union DParts p;
  635.     char bytes[8];
  636.     char hex[16+1];
  637.  
  638.     p.d = f;
  639.  
  640.     ConvertToIeeeDouble(f, bytes);
  641.     Bytes2Hex(bytes, hex, 8);
  642. #ifdef IEEE
  643.     fprintf(stderr, "double(%g) [%08lX %08lX] --> IEEE(%g) [%.8s %.8s]\n",
  644.         f, p.i[0], p.i[1],
  645.         MachineIEEEDouble(bytes),
  646.         hex, hex+8
  647.     );
  648. #else /* IEEE */
  649.     fprintf(stderr, "double(%g) [%08lX %08lX] --> IEEE[%.8s %.8s]\n",
  650.         f, p.i[0], p.i[1], hex, hex+8
  651.     );
  652. #endif /* IEEE */
  653.  
  654. }
  655.  
  656.  
  657. void
  658. TestFromIeeeExtended(hex)
  659. char *hex;
  660. {
  661.     defdouble f;
  662.     union EParts p;
  663.     char bytes[12];
  664.  
  665.     Hex2Bytes(hex, bytes);
  666.     f = ConvertFromIeeeExtended(bytes);
  667.     p.e = f;
  668.  
  669.     bytes[11] = bytes[9];
  670.     bytes[10] = bytes[8];
  671.     bytes[9] = bytes[7];
  672.     bytes[8] = bytes[6];
  673.     bytes[7] = bytes[5];
  674.     bytes[6] = bytes[4];
  675.     bytes[5] = bytes[3];
  676.     bytes[4] = bytes[2];
  677.     bytes[3] = 0;
  678.     bytes[2] = 0;
  679.  
  680. #if defined(applec) || defined(THINK_C) || defined(METROWERKS)
  681.     fprintf(stderr, "IEEE(%g) [%.4s %.8s %.8s] --> extended(%g) [%04X %04X%04X %04X%04X]\n",
  682.         *((defdouble*)(bytes)),
  683.         hex, hex+4, hex+12, f,
  684.         p.i[0]&0xFFFF, p.i[2]&0xFFFF, p.i[3]&0xFFFF, p.i[4]&0xFFFF, p.i[5]&0xFFFF
  685.     );
  686. #else /* !Macintosh */
  687.     fprintf(stderr, "IEEE[%.4s %.8s %.8s] --> extended(%g) [%04X %04X%04X %04X%04X]\n",
  688.         hex, hex+4, hex+12, f,
  689.         p.i[0]&0xFFFF, p.i[2]&0xFFFF, p.i[3]&0xFFFF, p.i[4]&0xFFFF, p.i[5]&0xFFFF
  690.     );
  691. #endif /* Macintosh */
  692. }
  693.  
  694.  
  695. void
  696. TestToIeeeExtended(f)
  697. defdouble f;
  698. {
  699.     char bytes[12];
  700.     char hex[24+1];
  701.  
  702.     ConvertToIeeeExtended(f, bytes);
  703.     Bytes2Hex(bytes, hex, 10);
  704.  
  705.     bytes[11] = bytes[9];
  706.     bytes[10] = bytes[8];
  707.     bytes[9] = bytes[7];
  708.     bytes[8] = bytes[6];
  709.     bytes[7] = bytes[5];
  710.     bytes[6] = bytes[4];
  711.     bytes[5] = bytes[3];
  712.     bytes[4] = bytes[2];
  713.     bytes[3] = 0;
  714.     bytes[2] = 0;
  715.  
  716. #if defined(applec) || defined(THINK_C) || defined(METROWERKS)
  717.     fprintf(stderr, "extended(%g) --> IEEE(%g) [%.4s %.8s %.8s]\n",
  718.         f, *((defdouble*)(bytes)),
  719.         hex, hex+4, hex+12
  720.     );
  721. #else /* !Macintosh */
  722.     fprintf(stderr, "extended(%g) --> IEEE[%.4s %.8s %.8s]\n",
  723.         f,
  724.         hex, hex+4, hex+12
  725.     );
  726. #endif /* Macintosh */
  727. }
  728.  
  729. #include    <signal.h>
  730.  
  731. void SignalFPE(i, j)
  732. int    i;
  733. void (*j)();
  734. {
  735.     fprintf(stderr, "[Floating Point Interrupt Caught.]\n", i, j);
  736.     signal(SIGFPE, SignalFPE);
  737. }
  738.     
  739. void
  740. main()
  741. {
  742.     long d[3];
  743.     char bytes[12];
  744.  
  745.     signal(SIGFPE, SignalFPE);
  746.  
  747.     TestFromIeeeSingle("00000000");
  748.     TestFromIeeeSingle("80000000");
  749.     TestFromIeeeSingle("3F800000");
  750.     TestFromIeeeSingle("BF800000");
  751.     TestFromIeeeSingle("40000000");
  752.     TestFromIeeeSingle("C0000000");
  753.     TestFromIeeeSingle("7F800000");
  754.     TestFromIeeeSingle("FF800000");
  755.     TestFromIeeeSingle("00800000");
  756.     TestFromIeeeSingle("00400000");
  757.     TestFromIeeeSingle("00000001");
  758.     TestFromIeeeSingle("80000001");
  759.     TestFromIeeeSingle("3F8FEDCB");
  760.     TestFromIeeeSingle("7FC00100");    /* Quiet NaN(1) */
  761.     TestFromIeeeSingle("7F800100");    /* Signalling NaN(1) */
  762.  
  763.     TestToIeeeSingle(0.0);
  764.     TestToIeeeSingle(-0.0);
  765.     TestToIeeeSingle(1.0);
  766.     TestToIeeeSingle(-1.0);
  767.     TestToIeeeSingle(2.0);
  768.     TestToIeeeSingle(-2.0);
  769.     TestToIeeeSingle(3.0);
  770.     TestToIeeeSingle(-3.0);
  771. #if !(defined(sgi) || defined(NeXT))
  772.     TestToIeeeSingle(HUGE_VAL);
  773.     TestToIeeeSingle(-HUGE_VAL);
  774. #endif
  775.  
  776. #ifdef IEEE
  777.     /* These only work on big-endian IEEE machines */
  778.     d[0] = 0x00800000L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));        /* Smallest normalized */
  779.     d[0] = 0x00400000L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));        /* Almost largest denormalized */
  780.     d[0] = 0x00000001L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));        /* Smallest denormalized */
  781.     d[0] = 0x00000001L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])) * 0.5);    /* Smaller than smallest denorm */
  782.     d[0] = 0x3F8FEDCBL; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));
  783. #if !(defined(sgi) || defined(NeXT))
  784.     d[0] = 0x7FC00100L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));        /* Quiet NaN(1) */
  785.     d[0] = 0x7F800100L; MaybeSwapBytes(d,4); TestToIeeeSingle(*((float*)(&d[0])));        /* Signalling NaN(1) */
  786. #endif /* sgi */
  787. #endif /* IEEE */
  788.  
  789.  
  790.  
  791.     TestFromIeeeDouble("0000000000000000");
  792.     TestFromIeeeDouble("8000000000000000");
  793.     TestFromIeeeDouble("3FF0000000000000");
  794.     TestFromIeeeDouble("BFF0000000000000");
  795.     TestFromIeeeDouble("4000000000000000");
  796.     TestFromIeeeDouble("C000000000000000");
  797.     TestFromIeeeDouble("7FF0000000000000");
  798.     TestFromIeeeDouble("FFF0000000000000");
  799.     TestFromIeeeDouble("0010000000000000");
  800.     TestFromIeeeDouble("0008000000000000");
  801.     TestFromIeeeDouble("0000000000000001");
  802.     TestFromIeeeDouble("8000000000000001");
  803.     TestFromIeeeDouble("3FFFEDCBA9876543");
  804.     TestFromIeeeDouble("7FF8002000000000");    /* Quiet NaN(1) */
  805.     TestFromIeeeDouble("7FF0002000000000");    /* Signalling NaN(1) */
  806.  
  807.     TestToIeeeDouble(0.0);
  808.     TestToIeeeDouble(-0.0);
  809.     TestToIeeeDouble(1.0);
  810.     TestToIeeeDouble(-1.0);
  811.     TestToIeeeDouble(2.0);
  812.     TestToIeeeDouble(-2.0);
  813.     TestToIeeeDouble(3.0);
  814.     TestToIeeeDouble(-3.0);
  815. #if !(defined(sgi) || defined(NeXT))
  816.     TestToIeeeDouble(HUGE_VAL);
  817.     TestToIeeeDouble(-HUGE_VAL);
  818. #endif
  819.  
  820. #ifdef IEEE
  821.     /* These only work on big-endian IEEE machines */
  822.     Hex2Bytes("0010000000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Smallest normalized */
  823.     Hex2Bytes("0010000080000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Normalized, problem with unsigned */
  824.     Hex2Bytes("0008000000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Almost largest denormalized */
  825.     Hex2Bytes("0000000080000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Denorm problem with unsigned */
  826.     Hex2Bytes("0000000000000001", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Smallest denormalized */
  827.     Hex2Bytes("0000000000000001", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)) * 0.5);    /* Smaller than smallest denorm */
  828.     Hex2Bytes("3FFFEDCBA9876543", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* accuracy test */
  829. #if !(defined(sgi) || defined(NeXT))
  830.     Hex2Bytes("7FF8002000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Quiet NaN(1) */
  831.     Hex2Bytes("7FF0002000000000", bytes); MaybeSwapBytes(d,8); TestToIeeeDouble(*((Double*)(bytes)));    /* Signalling NaN(1) */
  832. #endif /* sgi */
  833. #endif /* IEEE */
  834.  
  835.     TestFromIeeeExtended("00000000000000000000");    /* +0 */
  836.     TestFromIeeeExtended("80000000000000000000");    /* -0 */
  837.     TestFromIeeeExtended("3FFF8000000000000000");    /* +1 */
  838.     TestFromIeeeExtended("BFFF8000000000000000");    /* -1 */
  839.     TestFromIeeeExtended("40008000000000000000");    /* +2 */
  840.     TestFromIeeeExtended("C0008000000000000000");    /* -2 */
  841.     TestFromIeeeExtended("7FFF0000000000000000");    /* +infinity */
  842.     TestFromIeeeExtended("FFFF0000000000000000");    /* -infinity */
  843.     TestFromIeeeExtended("7FFF8001000000000000");    /* Quiet NaN(1) */
  844.     TestFromIeeeExtended("7FFF0001000000000000");    /* Signalling NaN(1) */
  845.     TestFromIeeeExtended("3FFFFEDCBA9876543210");    /* accuracy test */
  846.  
  847.     TestToIeeeExtended(0.0);
  848.     TestToIeeeExtended(-0.0);
  849.     TestToIeeeExtended(1.0);
  850.     TestToIeeeExtended(-1.0);
  851.     TestToIeeeExtended(2.0);
  852.     TestToIeeeExtended(-2.0);
  853. #if !(defined(sgi) || defined(NeXT))
  854.     TestToIeeeExtended(HUGE_VAL);
  855.     TestToIeeeExtended(-HUGE_VAL);
  856. #endif /* sgi */
  857.  
  858. #if defined(applec) || defined(THINK_C) || defined(METROWERKS)
  859.     Hex2Bytes("7FFF00008001000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes)));    /* Quiet NaN(1) */
  860.     Hex2Bytes("7FFF00000001000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes)));    /* Signalling NaN(1) */
  861.     Hex2Bytes("7FFE00008000000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  862.     Hex2Bytes("000000008000000000000000", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  863.     Hex2Bytes("000000000000000000000001", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  864.     Hex2Bytes("3FFF0000FEDCBA9876543210", bytes); TestToIeeeExtended(*((long double*)(bytes)));
  865. #endif
  866. }
  867.  
  868.  
  869. /* This is the output of the test program on an IEEE machine:
  870. IEEE(0) [00000000] --> float(0) [00000000]
  871. IEEE(-0) [80000000] --> float(-0) [80000000]
  872. IEEE(1) [3F800000] --> float(1) [3F800000]
  873. IEEE(-1) [BF800000] --> float(-1) [BF800000]
  874. IEEE(2) [40000000] --> float(2) [40000000]
  875. IEEE(-2) [C0000000] --> float(-2) [C0000000]
  876. IEEE(INF) [7F800000] --> float(INF) [7F800000]
  877. IEEE(-INF) [FF800000] --> float(-INF) [FF800000]
  878. IEEE(1.17549e-38) [00800000] --> float(1.17549e-38) [00800000]
  879. IEEE(5.87747e-39) [00400000] --> float(5.87747e-39) [00400000]
  880. IEEE(1.4013e-45) [00000001] --> float(1.4013e-45) [00000001]
  881. IEEE(-1.4013e-45) [80000001] --> float(-1.4013e-45) [80000001]
  882. IEEE(1.12444) [3F8FEDCB] --> float(1.12444) [3F8FEDCB]
  883. IEEE(NAN(001)) [7FC00100] --> float(INF) [7F800000]
  884. IEEE(NAN(001)) [7F800100] --> float(INF) [7F800000]
  885. float(0) [00000000] --> IEEE(0) [00000000]
  886. float(-0) [80000000] --> IEEE(0) [00000000]
  887. float(1) [3F800000] --> IEEE(1) [3F800000]
  888. float(-1) [BF800000] --> IEEE(-1) [BF800000]
  889. float(2) [40000000] --> IEEE(2) [40000000]
  890. float(-2) [C0000000] --> IEEE(-2) [C0000000]
  891. float(3) [40400000] --> IEEE(3) [40400000]
  892. float(-3) [C0400000] --> IEEE(-3) [C0400000]
  893. float(INF) [7F800000] --> IEEE(INF) [7F800000]
  894. float(-INF) [FF800000] --> IEEE(-INF) [FF800000]
  895. float(1.17549e-38) [00800000] --> IEEE(1.17549e-38) [00800000]
  896. float(5.87747e-39) [00400000] --> IEEE(5.87747e-39) [00400000]
  897. float(1.4013e-45) [00000001] --> IEEE(1.4013e-45) [00000001]
  898. float(7.00649e-46) [00000000] --> IEEE(0) [00000000]
  899. float(1.12444) [3F8FEDCB] --> IEEE(1.12444) [3F8FEDCB]
  900. float(NAN(001)) [7FC00100] --> IEEE(INF) [7F800000]
  901. float(NAN(001)) [7FC00100] --> IEEE(INF) [7F800000]
  902. IEEE(0) [00000000 00000000] --> double(0) [00000000 00000000]
  903. IEEE(-0) [80000000 00000000] --> double(-0) [80000000 00000000]
  904. IEEE(1) [3FF00000 00000000] --> double(1) [3FF00000 00000000]
  905. IEEE(-1) [BFF00000 00000000] --> double(-1) [BFF00000 00000000]
  906. IEEE(2) [40000000 00000000] --> double(2) [40000000 00000000]
  907. IEEE(-2) [C0000000 00000000] --> double(-2) [C0000000 00000000]
  908. IEEE(INF) [7FF00000 00000000] --> double(INF) [7FF00000 00000000]
  909. IEEE(-INF) [FFF00000 00000000] --> double(-INF) [FFF00000 00000000]
  910. IEEE(2.22507e-308) [00100000 00000000] --> double(2.22507e-308) [00100000 00000000]
  911. IEEE(1.11254e-308) [00080000 00000000] --> double(1.11254e-308) [00080000 00000000]
  912. IEEE(4.94066e-324) [00000000 00000001] --> double(4.94066e-324) [00000000 00000001]
  913. IEEE(-4.94066e-324) [80000000 00000001] --> double(-4.94066e-324) [80000000 00000001]
  914. IEEE(1.99556) [3FFFEDCB A9876543] --> double(1.99556) [3FFFEDCB A9876543]
  915. IEEE(NAN(001)) [7FF80020 00000000] --> double(INF) [7FF00000 00000000]
  916. IEEE(NAN(001)) [7FF00020 00000000] --> double(INF) [7FF00000 00000000]
  917. double(0) [00000000 00000000] --> IEEE(0) [00000000 00000000]
  918. double(-0) [80000000 00000000] --> IEEE(0) [00000000 00000000]
  919. double(1) [3FF00000 00000000] --> IEEE(1) [3FF00000 00000000]
  920. double(-1) [BFF00000 00000000] --> IEEE(-1) [BFF00000 00000000]
  921. double(2) [40000000 00000000] --> IEEE(2) [40000000 00000000]
  922. double(-2) [C0000000 00000000] --> IEEE(-2) [C0000000 00000000]
  923. double(3) [40080000 00000000] --> IEEE(3) [40080000 00000000]
  924. double(-3) [C0080000 00000000] --> IEEE(-3) [C0080000 00000000]
  925. double(INF) [7FF00000 00000000] --> IEEE(INF) [7FF00000 00000000]
  926. double(-INF) [FFF00000 00000000] --> IEEE(-INF) [FFF00000 00000000]
  927. double(2.22507e-308) [00100000 00000000] --> IEEE(2.22507e-308) [00100000 00000000]
  928. double(2.22507e-308) [00100000 80000000] --> IEEE(2.22507e-308) [00100000 80000000]
  929. double(1.11254e-308) [00080000 00000000] --> IEEE(1.11254e-308) [00080000 00000000]
  930. double(1.061e-314) [00000000 80000000] --> IEEE(1.061e-314) [00000000 80000000]
  931. double(4.94066e-324) [00000000 00000001] --> IEEE(4.94066e-324) [00000000 00000001]
  932. double(4.94066e-324) [00000000 00000001] --> IEEE(4.94066e-324) [00000000 00000001]
  933. double(1.99556) [3FFFEDCB A9876543] --> IEEE(1.99556) [3FFFEDCB A9876543]
  934. double(NAN(001)) [7FF80020 00000000] --> IEEE(INF) [7FF00000 00000000]
  935. double(NAN(001)) [7FF80020 00000000] --> IEEE(INF) [7FF00000 00000000]
  936. IEEE(0) [0000 00000000 00000000] --> extended(0) [0000 00000000 00000000]
  937. IEEE(-0) [8000 00000000 00000000] --> extended(-0) [8000 00000000 00000000]
  938. IEEE(1) [3FFF 80000000 00000000] --> extended(1) [3FFF 80000000 00000000]
  939. IEEE(-1) [BFFF 80000000 00000000] --> extended(-1) [BFFF 80000000 00000000]
  940. IEEE(2) [4000 80000000 00000000] --> extended(2) [4000 80000000 00000000]
  941. IEEE(-2) [C000 80000000 00000000] --> extended(-2) [C000 80000000 00000000]
  942. IEEE(INF) [7FFF 00000000 00000000] --> extended(INF) [7FFF 00000000 00000000]
  943. IEEE(-INF) [FFFF 00000000 00000000] --> extended(-INF) [FFFF 00000000 00000000]
  944. IEEE(NAN(001)) [7FFF 80010000 00000000] --> extended(INF) [7FFF 00000000 00000000]
  945. IEEE(NAN(001)) [7FFF 00010000 00000000] --> extended(INF) [7FFF 00000000 00000000]
  946. IEEE(1.99111) [3FFF FEDCBA98 76543210] --> extended(1.99111) [3FFF FEDCBA98 76543210]
  947. extended(0) --> IEEE(0) [0000 00000000 00000000]
  948. extended(-0) --> IEEE(0) [0000 00000000 00000000]
  949. extended(1) --> IEEE(1) [3FFF 80000000 00000000]
  950. extended(-1) --> IEEE(-1) [BFFF 80000000 00000000]
  951. extended(2) --> IEEE(2) [4000 80000000 00000000]
  952. extended(-2) --> IEEE(-2) [C000 80000000 00000000]
  953. extended(INF) --> IEEE(INF) [7FFF 00000000 00000000]
  954. extended(-INF) --> IEEE(-INF) [FFFF 00000000 00000000]
  955. extended(NAN(001)) --> IEEE(INF) [7FFF 00000000 00000000]
  956. extended(NAN(001)) --> IEEE(INF) [7FFF 00000000 00000000]
  957. extended(5.94866e+4931) --> IEEE(5.94866e+4931) [7FFE 80000000 00000000]
  958. extended(1e-4927) --> IEEE(1e-4927) [0000 80000000 00000000]
  959. extended(1e-4927) --> IEEE(1e-4927) [0000 00000000 00000001]
  960. extended(1.99111) --> IEEE(1.99111) [3FFF FEDCBA98 76543210]
  961. */
  962.  
  963. #endif /* TEST_FP */
  964.  
  965. #endif /* #if 0*/
  966.